﻿using System;
using Hvam.SharePoint.Search.Query.Site.Models;
using Hvam.SharePoint.Search.Query.Site.ResultSteps;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Hvam.SharePoint.Search.Tests.Internal.Query.Site.ResultSteps
{
    [TestClass]
    public class FieldExtractorResultStepTests
    {
        [TestMethod]
        public void ProcessDecimalPercentTest()
        {
            // Arrange
            using (var site = new SPSite(TestConstants.Site))
            {
                using (var web = site.OpenWeb())
                {
                    var name = Guid.NewGuid().ToString().Replace("-", string.Empty);
                    var guid = web.Lists.Add(name, name, SPListTemplateType.Tasks);
                    var list = web.Lists[guid];

                    var item = list.Items.Add();
                    item[SPBuiltInFieldId.Title] = "Title";
                    item[SPBuiltInFieldId.PercentComplete] = 0.42;
                    item.Update();

                    var query = new SiteSearchQuery(string.Format("site:\"{0}\"", TestConstants.Site));
                    query.RequestedProperties.Add("percentcomplete");

                    var field = web.AvailableFields[SPBuiltInFieldId.PercentComplete];
                    query.RequestedFields.Add("percentcomplete", field);

                    var step = new FieldExtractorResultStep(query);
                    var result =
                        new SiteSearchResult
                            {
                                ListItem = item
                            };

                    // Act
                    step.Process(result);

                    // Assert
                    list.Delete();

                    Assert.IsTrue(result.Properties.ContainsKey("percentcomplete"));
                    var value = result.Properties["percentcomplete"];
                    Assert.AreEqual("0,42", value);
                }
            }
        }

        [TestMethod]
        public void ProcessDateTimeTest()
        {
            // Arrange
            using (var site = new SPSite(TestConstants.Site))
            {
                using (var web = site.OpenWeb())
                {
                    var name = Guid.NewGuid().ToString().Replace("-", string.Empty);
                    var guid = web.Lists.Add(name, name, SPListTemplateType.Tasks);
                    var list = web.Lists[guid];

                    var item = list.Items.Add();
                    item[SPBuiltInFieldId.Title] = "Title";
                    item[SPBuiltInFieldId.TaskDueDate] = new DateTime(2012, 1, 16, 0, 0, 0);
                    item.Update();

                    var query = new SiteSearchQuery(string.Format("site:\"{0}\"", TestConstants.Site));
                    query.RequestedProperties.Add("taskduedate");

                    var field = web.AvailableFields[SPBuiltInFieldId.TaskDueDate];
                    query.RequestedFields.Add("taskduedate", field);

                    var step = new FieldExtractorResultStep(query);
                    var result = 
                        new SiteSearchResult
                            {
                                ListItem = item
                            };

                    // Act
                    step.Process(result);

                    // Assert
                    list.Delete();

                    Assert.IsTrue(result.Properties.ContainsKey("taskduedate"));
                    var value = result.Properties["taskduedate"];
                    Assert.AreEqual("2012-01-15T23:00:00Z", value);

                    var date = SPUtility.CreateDateTimeFromISO8601DateTimeString(value);
                    Assert.AreEqual("1/16/2012 12:00 AM", SPUtility.FormatDate(web, date, SPDateFormat.DateTime));
                }
            }
        }

        [TestMethod]
        public void ProcessUserTest()
        {
            // Arrange
            using (var site = new SPSite(TestConstants.Site))
            {
                using (var web = site.OpenWeb())
                {
                    var name = Guid.NewGuid().ToString().Replace("-", string.Empty);
                    var guid = web.Lists.Add(name, name, SPListTemplateType.Tasks);
                    var list = web.Lists[guid];

                    var item = list.Items.Add();
                    item[SPBuiltInFieldId.Title] = "Title";
                    item[SPBuiltInFieldId.AssignedTo] = web.CurrentUser;
                    item.Update();

                    var query = new SiteSearchQuery(string.Format("site:\"{0}\"", TestConstants.Site));
                    query.RequestedProperties.Add("assignedto");

                    var field = web.AvailableFields[SPBuiltInFieldId.AssignedTo];
                    query.RequestedFields.Add("assignedto", field);

                    var step = new FieldExtractorResultStep(query);
                    var result =
                        new SiteSearchResult
                            {
                                ListItem = item
                            };

                    // Act
                    step.Process(result);

                    // Assert
                    list.Delete();

                    Assert.IsTrue(result.Properties.ContainsKey("assignedto"));
                    var value = result.Properties["assignedto"];
                    Assert.AreEqual(web.CurrentUser.Name, value);
                }
            }
        }

        [TestMethod]
        public void ProcessYesNoTest()
        {
            // Arrange
            using (var site = new SPSite(TestConstants.Site))
            {
                using (var web = site.OpenWeb())
                {
                    var name = Guid.NewGuid().ToString().Replace("-", string.Empty);
                    var guid = web.Lists.Add(name, name, SPListTemplateType.GenericList);
                    var list = web.Lists[guid];

                    list.Fields.Add("NoField", SPFieldType.Boolean, false);
                    list.Fields.Add("YesField", SPFieldType.Boolean, false);

                    var noField = list.Fields["NoField"];
                    var yesField = list.Fields["YesField"];

                    var item = list.Items.Add();
                    item[SPBuiltInFieldId.Title] = "Title";
                    item[noField.Id] = false;
                    item[yesField.Id] = true;
                    item.Update();

                    var query = new SiteSearchQuery(string.Format("site:\"{0}\"", TestConstants.Site));
                    query.RequestedProperties.Add("nofield");
                    query.RequestedProperties.Add("yesfield");

                    query.RequestedFields.Add("nofield", noField);
                    query.RequestedFields.Add("yesfield", yesField);

                    var step = new FieldExtractorResultStep(query);
                    var result = 
                        new SiteSearchResult
                            {
                                ListItem = item
                            };

                    // Act
                    step.Process(result);

                    // Assert
                    list.Delete();

                    Assert.IsTrue(result.Properties.ContainsKey("nofield"));
                    Assert.IsTrue(result.Properties.ContainsKey("yesfield"));
                    var noValue = result.Properties["nofield"];
                    Assert.AreEqual("False", noValue);
                    var yesValue = result.Properties["yesfield"];
                    Assert.AreEqual("True", yesValue);
                }
            }
        }
    }
}
